package api

import (
	"strconv"

	"github.com/gin-gonic/gin"

	pageApp "BookStack/internal/application/page"
	"BookStack/internal/interfaces/middleware"
	"BookStack/internal/interfaces/presenter"
)

// PageHandler 自定义页面处理器
type PageHandler struct {
	pageService pageApp.Service
	response    presenter.ResponseFormatter
}

// NewPageHandler 创建自定义页面处理器
func NewPageHandler(pageService pageApp.Service) *PageHandler {
	return &PageHandler{
		pageService: pageService,
		response:    presenter.NewResponseFormatter(),
	}
}

// RegisterRoutes 注册路由
func (h *PageHandler) RegisterRoutes(r *gin.RouterGroup) {
	// 公开接口
	public := r.Group("/page")
	{
		public.GET("/list", h.ListPages)
		public.GET("", h.GetPage) // 支持通过id或slug参数获取页面
	}

	// 需要认证的API
	auth := r.Group("/page")
	auth.Use(middleware.JWTAuth()) // 认证中间件
	{
		// 这里可以添加需要用户认证的API
	}

	// 管理员接口
	admin := r.Group("/admin/page")
	admin.Use(middleware.JWTAuth(), middleware.AdminAuth()) // 管理员权限认证中间件
	{
		admin.POST("", h.CreatePage)
		admin.PUT("/:id", h.UpdatePage)
		admin.DELETE("/:id", h.DeletePage)
		admin.PUT("/:id/status", h.SetPageStatus)
	}
}

// ListPages 获取页面列表
// @Summary 获取自定义页面列表
// @Description 获取所有可见的自定义页面列表
// @Tags 页面
// @Accept json
// @Produce json
// @Param page query int false "页码，默认为1"
// @Param page_size query int false "每页数量，默认为20，最大100"
// @Param status query int false "页面状态，默认为1(已发布)"
// @Success 200 {object} response.Response{data=page.PageListResponse}
// @Router /api/v1/page/list [get]
func (h *PageHandler) ListPages(c *gin.Context) {
	var params pageApp.PageListQueryParams
	if err := c.ShouldBindQuery(&params); err != nil {
		c.Error(err)
		return
	}

	// 设置默认值
	if params.Page <= 0 {
		params.Page = 1
	}
	if params.PageSize <= 0 {
		params.PageSize = 10
	} else if params.PageSize > 10 {
		params.PageSize = 10
	}

	// 公开API默认只查询已发布状态的页面
	if params.Status == nil {
		published := 1 // 已发布状态
		params.Status = &published
	}

	result, err := h.pageService.ListPages(c.Request.Context(), &params)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, result)
}

// GetPage 获取页面详情（支持通过id或slug）
// @Summary 获取自定义页面详情
// @Description 获取指定ID或Slug的自定义页面详情
// @Tags 页面
// @Accept json
// @Produce json
// @Param id query string false "页面ID"
// @Param slug query string false "页面别名"
// @Success 200 {object} response.Response{data=page.PageResponse}
// @Router /api/v1/page [get]
func (h *PageHandler) GetPage(c *gin.Context) {
	id := c.Query("id")
	slug := c.Query("slug")

	if id != "" {
		// 通过ID获取
		pageID, err := strconv.ParseUint(id, 10, 32)
		if err != nil {
			c.Error(pageApp.ValidationError("id", "无效的页面ID"))
			return
		}

		result, err := h.pageService.GetPageByID(c.Request.Context(), uint(pageID))
		if err != nil {
			c.Error(err)
			return
		}

		h.response.Success(c, result)
		return
	} else if slug != "" {
		// 通过Slug获取
		result, err := h.pageService.GetPageBySlug(c.Request.Context(), slug)
		if err != nil {
			c.Error(err)
			return
		}

		h.response.Success(c, result)
		return
	}

	// 参数不足
	c.Error(pageApp.ValidationError("params", "请提供id或slug参数"))
}

// CreatePage 创建自定义页面
// @Summary 创建自定义页面
// @Description 创建新的自定义页面
// @Tags 页面
// @Accept json
// @Produce json
// @Param page body page.CreatePageRequest true "页面信息"
// @Success 201 {object} response.Response{data=page.PageResponse}
// @Router /api/v1/admin/page [post]
func (h *PageHandler) CreatePage(c *gin.Context) {
	var req pageApp.CreatePageRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.Error(err)
		return
	}

	// 获取当前用户ID
	userID, err := middleware.GetUserID(c)
	if err != nil {
		c.Error(err)
		return
	}

	result, err := h.pageService.CreatePage(c.Request.Context(), &req, userID)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Created(c, result)
}

// UpdatePage 更新自定义页面
// @Summary 更新自定义页面
// @Description 更新现有自定义页面
// @Tags 页面
// @Accept json
// @Produce json
// @Param id path int true "页面ID"
// @Param page body page.UpdatePageRequest true "页面信息"
// @Success 200 {object} response.Response{data=page.PageResponse}
// @Router /api/v1/admin/page/{id} [put]
func (h *PageHandler) UpdatePage(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(pageApp.ValidationError("id", "无效的页面ID"))
		return
	}

	var req pageApp.UpdatePageRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.Error(err)
		return
	}

	// 获取当前用户ID
	userID, err := middleware.GetUserID(c)
	if err != nil {
		c.Error(err)
		return
	}

	result, err := h.pageService.UpdatePage(c.Request.Context(), uint(id), &req, userID)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, result)
}

// DeletePage 删除自定义页面
// @Summary 删除自定义页面
// @Description 删除自定义页面
// @Tags 页面
// @Accept json
// @Produce json
// @Param id path int true "页面ID"
// @Success 200 {object} response.Response
// @Router /api/v1/admin/page/{id} [delete]
func (h *PageHandler) DeletePage(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(pageApp.ValidationError("id", "无效的页面ID"))
		return
	}

	// 获取当前用户ID
	userID, err := middleware.GetUserID(c)
	if err != nil {
		c.Error(err)
		return
	}

	if err := h.pageService.DeletePage(c.Request.Context(), uint(id), userID); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// SetPageStatus 设置页面状态
// @Summary 设置自定义页面状态
// @Description 设置自定义页面的状态（发布、草稿等）
// @Tags 页面
// @Accept json
// @Produce json
// @Param id path int true "页面ID"
// @Param status body page.SetPageStatusRequest true "状态信息"
// @Success 200 {object} response.Response{data=page.PageResponse}
// @Router /api/v1/admin/page/{id}/status [put]
func (h *PageHandler) SetPageStatus(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(pageApp.ValidationError("id", "无效的页面ID"))
		return
	}

	var req pageApp.SetPageStatusRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.Error(err)
		return
	}

	// 获取当前用户ID
	userID, err := middleware.GetUserID(c)
	if err != nil {
		c.Error(err)
		return
	}

	result, err := h.pageService.SetPageStatus(c.Request.Context(), uint(id), &req, userID)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, result)
}
